package cn.raven;

import cn.raven.util.ESClientUtil;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;

import java.util.HashMap;

public class TestES {

    /**
    * @Title: testAdd
    * @Description: 通过索引+类型+id创建文档
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/24 19:33
    * @Parameters: []
    * @Return void
      */
    @Test
    public void testAdd() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 2.准备要放入到ES中的数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("id", 1);
        map.put("name", "尼古拉斯NB");
        map.put("age", 18);
        map.put("sex", 1);
        // 3.使用链式编程，将数据存入到ES中
        IndexRequestBuilder builder = client.prepareIndex("pethome", "user", "1").setSource(map);
        // 4.得到添加文档结果
        System.out.println(builder.get());
        // 5.关闭连接
        client.close();
    }


    /** 
    * @Title: testGet
    * @Description: 测试根据Id查询文档
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/24 19:29  
    * @Parameters: []
    * @Return void
      */
    @Test
    public void testGet() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 2.获取指定文档
        GetResponse response = client.prepareGet("pethome", "user", "5").get();
        System.out.println(response);
        System.out.println(response.getSource());
        // 3.关闭连接
        client.close();
    }
    
    /** 
    * @Title: testUpt
    * @Description: 根据ID修改文档
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/24 19:30  
    * @Parameters: []
    * @Return void
      */
    @Test
    public void testUpt() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 2.准备要修改的数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", "天下武功！唯快不破");
        // 3.使用链式编程，将要修改的数据存入到ES中
        UpdateResponse response = client.prepareUpdate("pethome", "user", "1").setDoc(map).get();
        // 4.得到修改结果
        System.out.println(response);
        // 5.关闭连接
        client.close();
    }
    
    /** 
    * @Title: testDel
    * @Description: 根据Id删除文档
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/24 19:32  
    * @Parameters: []
    * @Return void
      */
    @Test
    public void testDel() throws Exception{
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 3.使用链式编程，删除指定文档
        DeleteResponse response = client.prepareDelete("pethome", "user", "1").get();
        // 4.得到删除结果
        System.out.println(response);
        // 5.关闭连接
        client.close();
    }


    /**
     * @Description: 批量添加数据
     * @Author: 笔上人间
     * @Date: 2022/7/24 19:35
     * @return: void
     **/
    @Test
    public void testBatch() throws Exception {
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 2.创建批量操作对象
        BulkRequestBuilder bulk = client.prepareBulk();
        // 3.批量创建文档，放入批量操作对象中
        for (int i = 2; i < 10; i++) {
            IndexRequestBuilder builder = client.prepareIndex("pethome", "user", i + "").setSource(
                    XContentFactory.jsonBuilder()
                            .startObject()
                            .field("id", i - 1)
                            .field("name", "啦啦啦啦德玛西亚" + i)
                            .field("age", i - 1)
                            .field("sex", i%2)
                            .endObject()
            );
            BulkResponse result = bulk.add(builder).get();
            System.out.println(result);
        }
        // 4.关闭连接
        client.close();
    }


    /**
     * @Description: 复杂查询
     * @Author: 笔上人间
     * @Date: 2022/7/23 0:04
     * @return: void
     **/
    @Test
    public void testComplex() throws Exception {
        // 1.获取ES连接
        TransportClient client = ESClientUtil.getClient();
        // 查询条件：- 查询用户表，name包含：德玛西亚，age在1~12之间，每页大小2，从二页开始查，按照age倒序
        // 2.得到搜索对象
        SearchRequestBuilder builder = client.prepareSearch("pethome");
        // 3.指定要搜索的类型
        builder.setTypes("user");
        // 4.指定Query搜索对象，当参数是接口时我们可以传递：接口的工具类、接口实现、匿名内部类，此处传递接口工具类
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 4.1.指定DSL查询，name包含我在源码
        boolQuery.must(QueryBuilders.matchQuery("name", "德玛西亚"));
        // 4.2.指定DSL过滤，age在1~12之间
        boolQuery.filter(QueryBuilders.rangeQuery("age").gte(1).lte(12)).filter(QueryBuilders.termQuery("sex", 1));
        // 4.3.将搜索条件放入到搜索对象中
        builder.setQuery(boolQuery);
        // 5.设置分页起始位置
        builder.setFrom(2);
        // 6.设置分页每页展示条数
        builder.setSize(2);
        // 7.设置排序，age倒序
        builder.addSort("age", SortOrder.DESC);
        // 8.得到结果进行打印
        SearchHits hits = builder.get().getHits();
        System.out.println("命中结果：" + hits.getTotalHits());
        for (SearchHit document : hits) {
            System.out.println(document.getSourceAsMap());
        }
    }
}
